package com.hp.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedHashMap;
import java.util.Map;

import net.sf.json.JSONObject;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;

/**
 * 通过百度地图接口，进行地址正逆解析
 */
public class LngAndLatUtil {
    public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        Map map = LngAndLatUtil.getLngAndLat("北京市海淀区上地十街10号");
        System.out.println(map.toString());

        System.out.println(getLngAndLat("113.667632", "34.75413"));
    }

    static String ak = "GikGvPEX50s1G3YvroTapg3Moc8A3BFR";

    //进行解析的一个方法（经纬度转地址名称）
    public static String getLngAndLat(String lng, String lat) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String address = null;
        Map<String, String> map = new LinkedHashMap();
        String url =
//                https://api.map.baidu.com/reverse_geocoding/v3/?ak=您的ak&output=json&coordtype=wgs84ll&location=31.225696563611,121.49884033194  //GET请求
                "https://api.map.baidu.com/reverse_geocoding/v3/?ak=" + ak + "&output=json&coordtype=wgs84ll&location=" + lat + "," + lng;
        String jsonString = LngAndLatUtil.loadJSON(url);
        System.out.println(jsonString);
        try {
            JSONObject obj = JSONObject.fromObject(jsonString);
            address = obj.getJSONObject("result").getString("formatted_address");
        } catch (Exception e) {
            map.put("error", "未找到相匹配的经纬度，请检查地址");
        }
        return address;
    }


    /**
     * 地址名称转经纬度
     */
    public static Map getLngAndLat(String address) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        Map<String, String> map = new LinkedHashMap();
        String url = "https://api.map.baidu.com/geocoding/v3/?address=" + address + "&output=json&ak=" + ak + "&callback=showLocation";
//                    https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation //GET请求
        String jsonString = LngAndLatUtil.doGet(url);
        System.out.println(jsonString);
        if (jsonString.indexOf("(") != -1 && jsonString.indexOf(")") != -1) {
            jsonString = jsonString.substring(jsonString.indexOf("(") + 1, jsonString.lastIndexOf(")"));
        }
        try {
//{"status":0,"result":{"location":{"lng":116.3084202915042,"lat":40.05703033345938},"precise":1,"confidence":80,"comprehension":100,"level":"门址"}}
            JSONObject obj = JSONObject.fromObject(jsonString);
            if (obj.getString("status").toString().equals("0")) {
                double lng = obj.getJSONObject("result").getJSONObject("location").getDouble("lng");
                double lat = obj.getJSONObject("result").getJSONObject("location").getDouble("lat");
                map.put("lng", getDecimal(lng) + "");
                map.put("lat", getDecimal(lat) + "");
            } else {
                map.put("error", "未找到相匹配的经纬度！");
                System.out.println("未找到相匹配的经纬度！");
            }
        } catch (Exception e) {
            map.put("error", "未找到相匹配的经纬度，请检查地址");
        }
        return map;
    }

    public static double getDecimal(double num) {
        if (Double.isNaN(num)) {
            return 0;
        }
        BigDecimal bd = new BigDecimal(num);
        num = bd.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
        return num;
    }

    //第二种 通过url访问
//在JAVA中，Java.net包里面的类是进行网络编程的，其中java.net.URL类和java.net.URLConection类使编程者方便地利用URL在Internet上进行网络通信。
    public static String loadJSON(String url) {
        StringBuilder json = new StringBuilder();
        try {
            URL oracle = new URL(url);//创建Url对象
            URLConnection yc = oracle.openConnection();//打开连接
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    yc.getInputStream(), "UTF-8"));//获取缓存输出器
            String inputLine = null;
//输出
            while ((inputLine = in.readLine()) != null) {
                json.append(inputLine);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json.toString();
    }

    public static String doGet(String url) {
        StringBuffer sb = new StringBuffer();
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Get请求
        HttpGet httpGet = new HttpGet(url);
        // 响应模型
        CloseableHttpResponse response = null;
        //缓冲读出器
        BufferedReader bufferedReader = null;
        try {
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                if (response.getEntity() != null) {
                    try {
                        //缓存读出器创建，同时将输入流和缓冲区大小设置好
                        bufferedReader = new BufferedReader
                                (new InputStreamReader(response.getEntity().getContent(), "UTF-8"), 8 * 1024);
                        String line = null;
                        while ((line = bufferedReader.readLine()) != null) {
                            sb.append(line);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return sb.toString();
        }
    }

}